#ifndef __SAMPLE_IO_H__
#define __SAMPLE_IO_H__ 1

#include "audio_formats.h"
#include "properties_reader.h"

/*
 *                o---------------o
 *  read EMBED    |     main      | write EMBED
 * -------------->|  embed data   |-------------->
 *                |               |
 *                | - - - - - - - |
 *  write EXTRACT |     main      | read EXTRACT
 * <--------------|  extract data |<--------------
 *                |               |
 *                o---------------o
 *
 * The main programm calls the read method from the ISampleIO instance. The
 * read method set the pAction reference to EMBED or EXTRACT therefore the
 * main programm knows if it should embed or extract. If the main embed datas
 * then it call the write method with pAction is EMBED or otherwise with
 * pAction is EXTRACT.
 *
 */
class ISampleIO
{
public:
	enum EAction
	{
		UNKNOWN_ACTION = 0,
		NO_ACTION,
		EMBED,
		EXTRACT,
		/**
		 * INTERLEAVED_EMBED_EXTRACT will be converted by CDeinterleaveIO into
		 * EMBED and EXTRACT.
		 * deinterleave = Splits one interleaved multichannel audio stream into
		 * many mono audio streams.
		 * samples are following ordered: EMBED | EXTRACT | EMBED | EXTRACT | ...
		 */
		INTERLEAVED_EMBED_EXTRACT,
	};

	ISampleIO() { }
	virtual ~ISampleIO() { }

	/*
	 * FIXXXME: init should be passed a properties reader, so the 
	 * interface is suitable for all implementations of the 
	 * ISampleIO interface which in turn knows which values
	 * to look for
	 */
	
	/**
	 * @note The instance of the properties reader will be freed (delete) by
	 *       the main programm and is not allowed by the deconstructor of
	 *       an inherit IO class.
	 *
	 * @param pConfig pointer to the properties reader
	 * @return 0 on success, -1 otherwise
	 */
	virtual int init(CPropertiesReader *pConfig) = 0;
	virtual int destroy() = 0;

	/**
	 * @param pData Array of bytes, read from media.
	 *        The buffer for data will be provided by the read method.
	 *        Therefore a void** and not a void* is needed.
	 * @param pAction displays what has to be done, it also enables the
	 *        direction from which data came from
	 * @return number of bytes read, 0 for EOF and -1 for a timeout or an error
	 */
	virtual int read(void** pData, EAction& pAction, int pTimeout = 500000) = 0;

	/**
	 * @param pData Address of the Buffer which will be written to the media.
	 * @param pAction displays what has to be done, it also enables the
	 *        direction from which data came from
	 * @param pLength Length/Size of the buffer (unit: byte)
	 * @return number of bytes written or -1 for an error
	 */
	virtual int write(void* pData, const EAction& pAction, int pLength) = 0;

	virtual NAudioFormats::SStreamInfo getStreamInfo() = 0;

private:
	ISampleIO(const ISampleIO& );
	ISampleIO& operator=(const ISampleIO& );
};

#endif
